﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VehicleScale.Models;
using VehicleScale.EntityMappers;
using System.Diagnostics;

namespace VehicleScale.DataAccess
{
    public class CategoryDataAccess : BaseDataAccess, ICategoryDataAccess
    {

        #region Properties

        private CategoryModel _searchObject;
        /// <summary>
        /// Search Object
        /// </summary>
        public CategoryModel SearchObject
        {
            get { return _searchObject; }
            set
            {
                if (_searchObject != value)
                {
                    _searchObject = value;
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Search item
        /// </summary>
        /// <returns></returns>
        public IList<CategoryModel> Searcher()
        {
            IList<CategoryModel> collection;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                IQueryable<Category> query = dataContext.Categories;
                if (!String.IsNullOrEmpty(_searchObject.CategoryID))
                {
                    query = query.Where(e => e.CategoryID.Contains(_searchObject.CategoryID));
                }
                if (!String.IsNullOrEmpty(_searchObject.CategoryName))
                {
                    query = query.Where(e => e.CategoryName.Contains(_searchObject.CategoryName));
                }

                collection = new List<CategoryModel>();
                foreach (var item in query)
                {
                    collection.Add(CategoryMapper.ToModel(item));
                }
            }
            return collection;
        } 

        /// <summary>
        /// Get all
        /// </summary>
        /// <returns></returns>
        public IList<CategoryModel> GetAll()
        {
            IList<CategoryModel> collection;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                IQueryable<Category> query = dataContext.Categories;

                collection = new List<CategoryModel>();
                foreach (var item in query)
                {
                    collection.Add(CategoryMapper.ToModel(item));
                }
            }

            return collection;
        } 

        /// <summary>
        /// Get item
        /// </summary>
        /// <returns></returns>
        public CategoryModel Get()
        {
            CategoryModel item = null;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                Category query = dataContext.Categories.FirstOrDefault();

                if (query != null) item = CategoryMapper.ToModel(query);
            }

            return item;
        } 

        /// <summary>
        /// Get last
        /// </summary>
        /// <returns></returns>
        public CategoryModel GetLast()
        {
            CategoryModel item = null;
            using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
            {
                Category query = dataContext.Categories.LastOrDefault();

                if (query != null) item = CategoryMapper.ToModel(query);
            }

            return item;
        } 

        /// <summary>
        /// Generate Auto ID
        /// </summary>
        /// <param name="dataContext"></param>
        /// <returns></returns>
        private string GenerateAutoID(DataClassesDataContext dataContext)
        {
            string id = String.Empty;
            int length = 20; // length default
            string prefix = String.Empty;
            string startNumber = "1";
            string defaultID = String.Empty;

            // Create Default Key
            Config config = dataContext.Configs.FirstOrDefault();
            if (config != null)
            {
                prefix = config.CategoryPrefix;
                length = config.CategoryCodeLength;
            }
            defaultID = prefix + startNumber.PadLeft(length, '0');

            // Create Automation Key
            var query = dataContext.Categories.Where(e =>
                e.CategoryID.StartsWith(prefix));
            if (query != null)
                id = query.Max(e => e.CategoryID);

            if (String.IsNullOrEmpty(id))
                id = defaultID;
            else
            {
                id = id.Remove(0, prefix.Length);
                int numberID;
                string suffix;
                if (Int32.TryParse(id, out numberID))
                {
                    numberID++;
                    suffix = numberID.ToString().PadLeft(length, '0');
                    id = prefix + suffix;
                }
                else
                {
                    id = defaultID;
                }
            }
            // End Create Automation Key
            return id;
        }

        /// <summary>
        /// Add
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Add(CategoryModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    if (String.IsNullOrEmpty(item.CategoryID))
                    {
                        item.CategoryID = GenerateAutoID(dataContext);
                    }

                    Category entity = new Category();
                    CategoryMapper.ToEntity(entity, item);
                    dataContext.Categories.InsertOnSubmit(entity);
                    dataContext.SubmitChanges();

                    result = true;
                    item.IsNew = false;
                    item.IsEdit = false;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        } 

        /// <summary>
        /// Add collection
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public bool Add(IList<CategoryModel> collection)
        {
            throw new NotImplementedException();
        }
        
        /// <summary>
        /// Edit item
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Edit(CategoryModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Category entity = dataContext.Categories.Where(e => e.CategoryID == item.CategoryID).SingleOrDefault();
                    if (entity != null)
                    {
                        CategoryMapper.ToEntity(entity, item);
                        dataContext.SubmitChanges();
                        result = true;
                        item.IsNew = false;
                        item.IsEdit = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        } 
        
        /// <summary>
        /// Edit collection
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public bool Edit(IList<CategoryModel> collection)
        {
            throw new NotImplementedException();
        } 
        
        /// <summary>
        /// Delete item
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Delete(CategoryModel item)
        {
            bool result = false;
            try
            {
                using (DataClassesDataContext dataContext = new DataClassesDataContext(base.ConnectionString))
                {
                    Category entity = dataContext.Categories.Where(e => e.CategoryID == item.CategoryID).SingleOrDefault();
                    if (entity != null)
                    {
                        dataContext.Categories.DeleteOnSubmit(entity);
                        dataContext.SubmitChanges();
                        result = true;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return result;
        } 
        
        /// <summary>
        /// Delete collection
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public bool Delete(IList<CategoryModel> collection)
        {
            throw new NotImplementedException();
        } 
        #endregion

    }
}
